﻿'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Codigo de proyecto: 306 F                                     
' Nombre proyecto: Framework Web LNK                            
' Nombre del módulo: AbmBase                                    
' Tarea/s relacionada/s: Master Pages                           
' Fecha creacion: 19/11/2009                                    
' Autor/es original/es: Mauro Cristy mcristy@cdt-ar.com         
' Fecha modificacion: No Aplica                                 
' Autor modificacion: No Aplica                                 
' R02 relacionados: 04                                          
' R03 relacionados: No Aplica                                   
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Imports Webparts

#Region "Public Delegates"
''' <summary>
''' Delegado manejador del evento Actualizando del AbmBase.
''' </summary>
''' <remarks>Para utilizar este evento, deberá crearse un método local con la misma firma que el evento en cuestión y configurarlo como manejador del mismo: AddHandler masterpage.Actualizando, AddressOf localActualizando</remarks>
''' <param name="cancela">Si se asigna TRUE a esta variable, se cancelará la grabación.</param>
Public Delegate Sub AbmBaseActualizandoHandler(ByRef cancela As Boolean)
''' <summary>
''' Delegado manejador del evento Actualizado del AbmBase.
''' </summary>
''' <remarks>Para utilizar este evento, deberá crearse un método local con la misma firma que el evento en cuestión y configurarlo como manejador del mismo: AddHandler masterpage.Actualizado, AddressOf localActualizado</remarks>
Public Delegate Sub AbmBaseActualizadoHandler()
''' <summary>
''' Delegado manejador del evento Display del AbmBase.
''' </summary>
''' <remarks>Para utilizar este evento, deberá crearse un método local con la misma firma que el evento en cuestión y configurarlo como manejador del mismo: AddHandler masterpage.Display, AddressOf localDisplay</remarks>
Public Delegate Sub AbmBaseDisplayHandler()
''' <summary>
''' Delegado manejador del evento Eliminando del AbmBase.
''' </summary>
''' <remarks>Para utilizar este evento, deberá crearse un método local con la misma firma que el evento en cuestión y configurarlo como manejador del mismo: AddHandler masterpage.Eliminando, AddressOf localEliminando</remarks>
''' <param name="cancela">Si se asigna TRUE a esta variable, se cancelará la grabación.</param>
Public Delegate Sub AbmBaseEliminandoHandler(ByRef cancela As Boolean)
''' <summary>
''' Delegado manejador del evento Eliminado del AbmBase.
''' </summary>
''' <remarks>Para utilizar este evento, deberá crearse un método local con la misma firma que el evento en cuestión y configurarlo como manejador del mismo: AddHandler masterpage.Eliminado, AddressOf localEliminado</remarks>
Public Delegate Sub AbmBaseEliminadoHandler()
''' <summary>
''' Delegado manejador del evento Editando del AbmBase.
''' </summary>
''' <remarks>Para utilizar este evento, deberá crearse un método local con la misma firma que el evento en cuestión y configurarlo como manejador del mismo: AddHandler masterpage.Editando, AddressOf localEditandoy</remarks>
Public Delegate Sub AbmBaseEditando()
''' <summary>
''' Delegado manejador del evento CompletarDatos del AbmBase.
''' </summary>
''' <remarks>Para utilizar este evento, deberá crearse un método local con la misma firma que el evento en cuestión y configurarlo como manejador del mismo: AddHandler masterpage.CompletarDatos, AddressOf localCompletarDatos</remarks>
''' <param name="dsDatos">Dataset que contiene los datos a grabar, los cuales pueden ser modificados.</param>
Public Delegate Sub AbmBaseCompletarDatosHandler(ByRef dsDatos As DataSet)

#End Region

Partial Public Class AbmBase
    Inherits System.Web.UI.MasterPage

#Region "Propiedades Publicas"

    Private _lblTitulo As String
    ''' <summary>
    ''' Label con el título del abm.
    ''' </summary>
    Public Property lblTitulo() As String
        Get
            Return _lblTitulo
        End Get
        Set(ByVal value As String)
            _lblTitulo = value
        End Set
    End Property

    Private _lblTabs As String
    ''' <summary>
    ''' Label con el título del tabAdicional1.
    ''' </summary>
    Public Property lblTabs() As String
        Get
            Return _lblTabs
        End Get
        Set(ByVal nom As String)
            _lblTabs = nom
        End Set
    End Property

    Private _lblTabs1 As String
    ''' <summary>
    ''' Label con el título del tabAdicional2.
    ''' </summary>
    Public Property lblTabs1() As String
        Get
            Return _lblTabs1
        End Get
        Set(ByVal nom As String)
            _lblTabs1 = nom
        End Set
    End Property

    Private _lblTabs2 As String
    ''' <summary>
    ''' Label con el título del tabAdicional3.
    ''' </summary>
    Public Property lblTabs2() As String
        Get
            Return _lblTabs2
        End Get
        Set(ByVal nom As String)
            _lblTabs2 = nom
        End Set
    End Property

    Private _lblTabs3 As String
    ''' <summary>
    ''' Label con el título del tabAdicional4.
    ''' </summary>
    Public Property lblTabs3() As String
        Get
            Return _lblTabs3
        End Get
        Set(ByVal nom As String)
            _lblTabs3 = nom
        End Set
    End Property

    Private _lblTabs4 As String
    ''' <summary>
    ''' Label con el título del tabAdicional5.
    ''' </summary>
    Public Property lblTabs4() As String
        Get
            Return _lblTabs4
        End Get
        Set(ByVal nom As String)
            _lblTabs4 = nom
        End Set
    End Property

    Private _lblTabs5 As String
    ''' <summary>
    ''' Label con el título del tabAdicional6.
    ''' </summary>
    Public Property lblTabs5() As String
        Get
            Return _lblTabs5
        End Get
        Set(ByVal nom As String)
            _lblTabs5 = nom
        End Set
    End Property

    Private _lblTabs6 As String
    ''' <summary>
    ''' Label con el título del tabAdicional7.
    ''' </summary>
    Public Property lblTabs6() As String
        Get
            Return _lblTabs6
        End Get
        Set(ByVal nom As String)
            _lblTabs6 = nom
        End Set
    End Property

    Private _lblTabs7 As String
    ''' <summary>
    ''' Label con el título del tabAdicional8.
    ''' </summary>
    Public Property lblTabs7() As String
        Get
            Return _lblTabs7
        End Get
        Set(ByVal nom As String)
            _lblTabs7 = nom
        End Set
    End Property

    Private _TabsAdicionales As Integer
    ''' <summary>
    ''' Indica la cantidad de tabs visibles
    ''' </summary>
    Public Property TabsAdicionales() As Integer
        Get
            Return _TabsAdicionales
        End Get
        Set(ByVal cantidad As Integer)
            _TabsAdicionales = cantidad
        End Set
    End Property

    Private _FiltrosBusqueda As String
    ''' <summary>
    ''' Lista con los nombres de los campos de la tabla principal que desean utilizarse como filtros de búsqueda.
    ''' </summary>
    ''' <remarks>Si se omite completar esta propiedad, se agregarán todos los campos de la tabla principal como filtros de búsqueda.</remarks>
    ''' <value>Lista de campos separada por comas.</value>
    Public Property FiltrosBusqueda() As String
        Get
            Return _FiltrosBusqueda
        End Get
        Set(ByVal value As String)
            _FiltrosBusqueda = value
        End Set
    End Property

    Private _ColumnasGrilla As String
    ''' <summary>
    ''' Lista con los nombres de los campos de la tabla principal que se desean incluir en la grilla de resultados de búsqueda.
    ''' </summary>
    ''' <remarks>Si se omite completar esta propiedad, se agregarán todos los campos de la tabla principal como columnas de la grilla.</remarks>
    ''' <value>Lista de campos separada por comas.</value>
    Public Property ColumnasGrilla() As String
        Get
            Return _ColumnasGrilla
        End Get
        Set(ByVal value As String)
            _ColumnasGrilla = value
        End Set
    End Property

    Private _CamposEdicion As String
    ''' <summary>
    ''' Lista con los nombres de los campos de la tabla principal que desean poder editarse.
    ''' </summary>
    ''' <remarks>
    ''' Esta propiedad es sólo utilizada en caso de los abms que se crean en runtime.
    ''' Si se omite completar esta propiedad, se editarán todos los campos de la tabla principal.
    ''' </remarks>
    ''' <value>Lista de campos separada por comas.</value>
    Public Property CamposEdicion() As String
        Get
            Return _CamposEdicion
        End Get
        Set(ByVal value As String)
            _CamposEdicion = value
        End Set
    End Property

    Private _AliasCampos As Hashtable
    ''' <summary>
    ''' Lista de pares de valores con los nombres de las columnas de la tabla principal y su alias, para utilizar en los labels de filtro, edición y los headers de las grillas.
    ''' </summary>
    ''' <remarks>Si se omite completar esta lista de valores, se tomará el nombre del campo de la tabla decodificando su nomenclatura en forma estándar.</remarks>
    ''' <value>Par doble de datos compuesto por ("nm_campo", "Alias del Campo")</value>
    Public Property AliasCampos() As Hashtable
        Get
            Return _AliasCampos
        End Get
        Set(ByVal value As Hashtable)
            _AliasCampos = value
        End Set
    End Property

    Private _camposforeingkey As Hashtable
    ''' <summary>
    ''' Lista de pares de valores con los nombres de campos que desea se muestren con un control de foreign key (lista desplegable) y los datos para dicha lista.
    ''' </summary>
    ''' <remarks>Los campos de la tabla principal que existan en esta lista utilizarán un control del tipo lista desplegable tanto en la solapa de filtros como en la de edición (en los abms automáticos).</remarks>
    ''' <value>Lista doble conteniendo como primer elemento el nombre del campo que desea se ingrese con una lista desplegable de valores, y como segundo elemento los datos para armar la lista (tabla, campo clave, campo descriptivo). Ej: CamposForeignKey.Add('cd_operador', 'wad_operadores, cd_operador, nm_operador').</value>
    Public Property CamposForeingKey() As Hashtable
        Get
            Return _camposforeingkey
        End Get
        Set(ByVal value As Hashtable)
            _camposforeingkey = value
        End Set
    End Property

    Private _EsUnAlta As Boolean
    ''' <summary>
    ''' Indica si se está realizando una operación de ALTA o MODIFICACION de un registro.
    ''' </summary>
    ''' <remarks>Utilizable en los eventos del abm para determinar acciones acordes a la operación de edición realizada.</remarks>
    ''' <value>TRUE si está realizando un ALTA de un registro.</value>
    Public Property lnk_EsUnAlta() As Boolean
        Get
            Return _EsUnAlta
        End Get
        Set(ByVal value As Boolean)
            _EsUnAlta = value
        End Set
    End Property

    Private _AltasOk As Boolean = True
    ''' <summary>
    ''' Indica si se permiten o no las operaciones de ALTA de registros.
    ''' </summary>
    ''' <value>TRUE si está permitido el ALTA de registros, FALSE caso contrario.</value>
    Public Property AltasOk() As Boolean
        Get
            Return _AltasOk
        End Get
        Set(ByVal value As Boolean)
            _AltasOk = value
            Me.cmdAdd.Visible = value
        End Set
    End Property

    Private _BajasOk As Boolean = True
    ''' <summary>
    ''' Indica si se permiten o no las operaciones de BAJA de registros.
    ''' </summary>
    ''' <value>TRUE si está permitida la BAJA de registros, FALSE caso contrario.</value>
    Public Property BajasOk() As Boolean
        Get
            Return _BajasOk
        End Get
        Set(ByVal value As Boolean)
            _BajasOk = value
            Me.cmdDelete.Visible = value
        End Set
    End Property

    Private _ModifOk As Boolean = True
    ''' <summary>
    ''' Indica si se permiten o no las operaciones de MODIFICACION de registros.
    ''' </summary>
    ''' <value>TRUE si está permitida la MODIFICACION de registros, FALSE caso contrario.</value>
    Public Property ModifOk() As Boolean
        Get
            Return _ModifOk
        End Get
        Set(ByVal value As Boolean)
            _ModifOk = value
            Me.cmdEdit.Visible = value
        End Set
    End Property

#End Region

#Region "Propiedades Privadas"

    Private _lnk_dataset As DataSet
    ''' <summary>
    ''' Dataset principal del abm.
    ''' </summary>
    Public Property Lnk_dataset() As DataSet
        Get
            Return _lnk_dataset
        End Get
        Set(ByVal value As DataSet)
            _lnk_dataset = value
        End Set
    End Property

    Private _tablaprincipal As String
    ''' <summary>
    ''' Tabla principal del abm.
    ''' </summary>
    Public Property TablaPrincipal() As String
        Get
            Return _tablaprincipal
        End Get
        Set(ByVal value As String)
            _tablaprincipal = value
        End Set
    End Property

    Private _ObjetoReglaNegocios As IAbm
    ''' <summary>
    ''' Objeto de reglas del negocio encargado de la grabación de la tabla principal del abm.
    ''' </summary>
    Public Property ObjetoReglaNegocios() As IAbm
        Get
            Return _ObjetoReglaNegocios
        End Get
        Set(ByVal value As IAbm)
            _ObjetoReglaNegocios = value
        End Set
    End Property

    Private _FiltroGlobal As String = ""
    ''' <summary>
    ''' Condición SQL-WHERE que se aplicará como filtro adicional a todas las búsquedas a realizar en el abm.
    ''' </summary>
    ''' <value>Expresión SQL-Where</value>
    Public Property FiltroGlobal() As String
        Get
            Return _FiltroGlobal
        End Get
        Set(ByVal value As String)
            _FiltroGlobal = value
        End Set
    End Property

    Private _ordenbusquedas As String
    Public Property OrdenBusquedas() As String
        Get
            Return _ordenbusquedas
        End Get
        Set(ByVal value As String)
            _ordenbusquedas = value
        End Set
    End Property

    Public Property SortExpression() As String
        Get
            If ViewState("SortExpression") Is Nothing Then
                Return String.Empty
            Else
                Return ViewState("SortExpression").ToString()
            End If
        End Get
        Set(ByVal Value As String)
            ViewState("SortExpression") = Value
        End Set
    End Property

    Public Property SortDirection() As String
        Get
            If ViewState("SortDirection") Is Nothing Then
                Return String.Empty
            Else
                Return ViewState("SortDirection").ToString()
            End If
        End Get
        Set(ByVal Value As String)
            ViewState("SortDirection") = Value
        End Set
    End Property
#End Region

#Region "Objetos Privados"
    Private tablaFiltrado As New Table
    Dim camposFK As New ArrayList()

    'Variable para confirmaciones en ModalPopups 
    Private Confirma As Boolean = False
#End Region

#Region "Eventos"

    ''' <summary>
    ''' Evento que se dispara antes de realizar la grabación (alta o modificación) del registro actual y permite cancelar la misma.
    ''' </summary>
    ''' <remarks>Este evento puede utilizarse para realizar validaciones y cancelar o no la grabación del registro.</remarks>
    Public Event Actualizando As AbmBaseActualizandoHandler
    ''' <summary>
    ''' Evento que se dispara después de realizar la grabación (alta o modificación) del registro actual.
    ''' </summary>
    ''' <remarks>Este evento puede utilizarse para disparar grabaciones adicionales.</remarks>
    Public Event Actualizado As AbmBaseActualizadoHandler
    ''' <summary>
    ''' Evento que se dispara cuando se despliega un registro en pantalla, ya sea para consultar, editar o luego de cancelar una edición.
    ''' </summary>
    ''' <remarks>Este evento suele ser útil para completar la información a mostrar en la página.</remarks>
    Public Event Display As AbmBaseDisplayHandler
    ''' <summary>
    ''' Evento que se dispara inmediatamente antes de permitir una eliminación del registro en pantalla, pudiendo cancelar la misma.
    ''' </summary>
    ''' <remarks>Este evento suele contener validaciones previas a la eliminación de un registro.</remarks>
    Public Event Eliminando As AbmBaseEliminandoHandler
    ''' <summary>
    ''' Evento que se dispara inmediatamente antes de iniciar la edición de un registro (por alta o modificación).
    ''' </summary>
    ''' <remarks>Suele utilizarse para ingresar valores por defecto en los campos a editar.</remarks>
    Public Event Eliminado As AbmBaseEliminadoHandler
    ''' <summary>
    ''' Evento que se dispara inmediatamente después de eliminar un registro.
    ''' </summary>
    ''' <remarks>Suele utilizarse para ingresar realizar operaciones adicionales asociadas a las bajas de registros.</remarks>
    Public Event Editando As AbmBaseEditando
    ''' <summary>
    ''' Evento que se dispara inmediatamente antes de grabar la información con el objeto de reglas del negocio y se utiliza para manipular el dataset que será grabado.
    ''' </summary>
    ''' <remarks>Generalmente es útil para completar datos en el dataset que llega por parámetro, como ser, campos de auditoría.</remarks>
    Public Event CompletarDatos As AbmBaseCompletarDatosHandler

    ''' <summary>
    ''' Carga la página y realiza toda la rutina de inicialización del formulario.
    ''' </summary>
    ''' <remarks>Se utiliza este método para inicializar las propiedades que determinan el funcionamiento del abm, instanciar un objeto de negocios y ejecutar el método InicializarPagina para enlazar la página actual con el abm base.</remarks>
    ''' <param name="sender">Objeto emisor del evento.</param>
    ''' <param name="e">Argumentos pasados por parámetro.</param>
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Page.EnableViewState = True

        'Graba Log de acceso
        If Not Page.IsPostBack Then
            Dim parametros As New ArrayList
            parametros.Add(Common.Env.Operador)
            parametros.Add(ObjetoReglaNegocios.getNombrePrograma())
            parametros.Add(DBNull.Value)
            parametros.Add("I")
            parametros.Add(Common.Env.Terminal)
            parametros.Add("Ingreso a la pagina web")
            parametros.Add(DBNull.Value)
            Sql.ExecSP(ConnectionString, "wp_grabar_log", parametros)

            Session("Estado") = "Consulta"

            'Carga el nombre del programa para que despues lo levante la pagina de ayuda
            Session("Programa") = ObjetoReglaNegocios.getNombrePrograma()
        End If

        divErroresEdicion.InnerHtml = String.Empty

    End Sub

    ''' <summary>
    ''' Ejecuta una búsqueda de datos en base a los filtros especificados y carga la grilla de resultados.
    ''' </summary>
    Protected Sub Buscar() Handles cmdSeek.Click
        Dim tablaPrincipal As DataTable
        'Flags
        Dim flagPK As Boolean = False
        Dim flagFK As Boolean = False
        'Variables para el armado de la consulta
        Dim tablasFrom As String
        Dim condicion As String = ""
        Dim CamposConsulta As String
        'Auxiliares
        Dim controlHtml As Control
        Dim controlId As String
        Dim controlText As String
        Dim aux As String()
        Dim contaFK As Integer = 0
        Dim sFiltroBusqueda As String = ""

        'Obtenemos la tabla principal de la consulta
        tablaPrincipal = Lnk_dataset.Tables(0)

        'Seteamos la tabla principal como primer tabla del FROM de la consulta
        tablasFrom = tablaPrincipal.TableName

        'Obtenemos los campos y valores para el filtro WHERE
        If FiltroGlobal <> String.Empty Then
            sFiltroBusqueda = FiltroGlobal & " AND "
        End If
        For x = 1 To tablaFiltrado.Rows.Count
            If x = 1 Then
                condicion = ""
            End If
            controlHtml = tablaFiltrado.Rows(x - 1).Cells(1).Controls(0)
            controlId = controlHtml.ID
            aux = Split(controlId, "filtro_")
            controlId = aux(1)

            'Seleccionamos los valores segun el tipo de dato del control
            Select Case controlHtml.GetType.Name
                Case "TextBox"
                    controlText = CType(controlHtml, TextBox).Text
                Case "DropDownList"
                    controlText = CType(controlHtml, DropDownList).SelectedItem.Value
                Case "RadioButtonList"
                    controlText = CType(controlHtml, RadioButtonList).SelectedItem.Value
                Case "CheckBox"
                    If CType(controlHtml, CheckBox).Checked Then
                        controlText = "1"
                    Else
                        controlText = "0"
                    End If
                Case Else
                    controlText = ""
            End Select


            If (controlText <> "" Or tablaPrincipal.Columns(controlId).DataType.Name = "DateTime") And flagFK = False Then
                If controlHtml.GetType.Name = "CheckBox" And controlText = "0" Then
                    sFiltroBusqueda &= condicion & " (" & controlId & " = 0 or " & controlId & " is null) "
                ElseIf controlHtml.GetType.Name = "CheckBox" And controlText = "1" Then
                    sFiltroBusqueda &= condicion & " " & controlId & " = 1 "
                Else
                    If tablaPrincipal.Columns(controlId).DataType.Name = "DateTime" Then
                        Dim controlText2 As String
                        controlHtml = tablaFiltrado.Rows(x - 1).Cells(1).Controls(6)
                        controlText2 = CType(controlHtml, TextBox).Text

                        Dim formatoFecha As New System.Globalization.DateTimeFormatInfo
                        formatoFecha.ShortDatePattern = "YYYYMMDD"

                        controlText = convertirFecha(controlText)
                        controlText2 = convertirFecha(controlText2)

                        If controlText = "" And controlText2 <> "" Then
                            'sFiltroBusqueda &= condicion & controlId & " <= '" & controlText2 & " 23:59:59' "
                            sFiltroBusqueda &= condicion & controlId & " <= " & StartFrame.SystemFunctions.Dates.DateToSql(controlText2) & " "
                        ElseIf controlText <> "" And controlText2 = "" Then
                            'sFiltroBusqueda &= condicion & controlId & " >= '" & controlText & " 00:00:00' "
                            sFiltroBusqueda &= condicion & controlId & " >= '" & StartFrame.SystemFunctions.Dates.DateToSql(controlText) & " "
                        ElseIf controlText <> "" And controlText2 <> "" Then
                            'sFiltroBusqueda &= condicion & " (" & controlId & " between '" & controlText & " 00:00:00' AND '" & controlText2 & " 23:59:59') "
                            sFiltroBusqueda &= condicion & " (" & controlId & " between " & StartFrame.SystemFunctions.Dates.DateToSql(controlText) & " AND " _
                                & StartFrame.SystemFunctions.Dates.DateToSql(controlText2) & ") "
                        End If

                    ElseIf tablaPrincipal.Columns(controlId).DataType.Name = "Boolean" Then
                        If controlText = "0" Then
                            sFiltroBusqueda &= condicion & " (" & controlId & " = 0 or " & controlId & " is null) "
                        ElseIf controlText = "1" Then
                            sFiltroBusqueda &= condicion & " " & controlId & " = 1 "
                        End If
                    Else
                        sFiltroBusqueda &= condicion & " " & controlId & " LIKE '%" & controlText & "%' "
                    End If
                End If
                condicion = "AND"
            End If
        Next
        If sFiltroBusqueda <> String.Empty AndAlso sFiltroBusqueda.Trim.Substring(sFiltroBusqueda.Length - 4) = "AND" Then
            sFiltroBusqueda = sFiltroBusqueda.Substring(0, sFiltroBusqueda.Length - 4)
        End If

        'Obtenemos los campos de la consulta
        If ColumnasGrilla = "" Then
            CamposConsulta = " tp.* "
        Else
            CamposConsulta = ""
            Dim sep As String = ""
            Dim camposPk As String = ""
            aux = ColumnasGrilla.Split(",")

            For Each campos As String In aux

                For Each pk In isPrimaryKey(tablaPrincipal.TableName)
                    If pk.ToString() = Trim(campos) Then
                        camposPk &= "tp." & pk & ", "
                        flagPK = True
                    End If
                Next

                If Not flagPK Then
                    CamposConsulta &= sep & "tp." & Trim(campos)
                    sep = ", "
                End If

                flagPK = False
            Next

            CamposConsulta = camposPk & CamposConsulta
        End If

        'Condicion de ordenamiento
        If OrdenBusquedas = String.Empty AndAlso Not ColumnasGrilla Is Nothing Then
            aux = ColumnasGrilla.Split(",")
            OrdenBusquedas = "tp." & aux(0)
        End If

        'Ejecutamos la consulta en el dataset, y la pasamos a la grilla de datos
        Lnk_dataset.Clear()
        Lnk_dataset = DA.Sql.Select(ConnectionString, CamposConsulta, tablasFrom & " AS tp", sFiltroBusqueda, OrdenBusquedas)

        'Agregamos los Nombres de campos customizados al dataset, para las cabeceras de la grilla
        If AliasCampos IsNot Nothing Then
            For i = 0 To Lnk_dataset.Tables(0).Columns.Count - 1
                If AliasCampos(Lnk_dataset.Tables(0).Columns(i).ColumnName) IsNot Nothing Then
                    Lnk_dataset.Tables(0).Columns(i).ColumnName = AliasCampos(Lnk_dataset.Tables(0).Columns(i).ColumnName)
                End If
            Next
        End If

        tablaDatos.DataSource = Lnk_dataset
        tablaDatos.DataBind()
        'tablaDatos.HeaderRow.Cells(0).Text = "Accion"
        'For i = 1 To tablaDatos.HeaderRow.Cells.Count - 1
        '    tablaDatos.HeaderRow.Cells(i).Text = "columna " & i.ToString
        'Next
        ViewState.Add("tablaDatosDataSource", Lnk_dataset.Tables(0))


        'Imprime la consulta debajo del formulario de filtrado, SOLO PARA DEBUG
        'Dim lala As New Label
        'lala.Text = "SELECT " & CamposConsulta & " FROM " & tablaPrincipal.TableName & " WHERE " & sFiltroBusqueda
        'divTabla.Controls.Add(lala)

    End Sub

    ''' <summary>
    ''' Elimina el registro seleccionado.
    ''' </summary>
    Protected Sub Eliminar() Handles cmdDelete.Click
        Dim keyRegSelected As Integer = -1
        Dim dsDatos As New DataSet
        Dim camposConsulta As String
        Dim tablaPrincipal As DataTable
        Dim aux As String()
        Dim flagPK As Boolean = False
        Dim cancela As Boolean = False

        'Obtenemos la informacion necesaria de la tabla con la cual trabajaremos
        tablaPrincipal = Lnk_dataset.Tables(0)
        keyRegSelected = tablaDatos.SelectedIndex

        If keyRegSelected <> -1 Then

            Try

                If Not Confirma Then
                    'Pregunta de confirmacion
                    ModalPopupExtender2.Show()

                    cancela = True
                End If

                RaiseEvent Eliminando(cancela)

                'Variable dependiente del evento Eliminando
                If Not cancela Then
                    Dim idRegSeleccionado As New ArrayList()
                    Dim conta As Integer = 1

                    Dim condicion As String = ""
                    Dim conector As String = ""
                    For Each pk In isPrimaryKey(tablaPrincipal.TableName)
                        condicion &= conector & Lnk_dataset.Tables(0).Columns(conta - 1).ColumnName & " = '" & tablaDatos.SelectedRow.Cells(conta).Text & "'"
                        conector = " AND "
                        conta += 1
                    Next

                    Lnk_dataset.Clear()
                    Lnk_dataset = DA.Sql.Select(ConnectionString, "*", tablaPrincipal.TableName, condicion)

                    Lnk_dataset.Tables(0).Rows(0).Delete()

                    'Se prpeara el dataset auxiliar para ejecutar los cambios en la base
                    dsDatos = Lnk_dataset.GetChanges()

                    If dsDatos Is Nothing Then
                        Lnk_dataset.RejectChanges()
                    Else
                        If dsDatos.Tables(0).HasErrors Then
                            divErroresEdicion.InnerHtml = "Ocurrio un error grabando datos, intentelo nuevamente"
                        Else
                            ObjetoReglaNegocios.setOperadorLogueado(Operador)
                            ObjetoReglaNegocios.ActualizarDatos(dsDatos)

                            RaiseEvent Eliminado()

                        End If
                    End If

                    'Obtenemos los campos de la consulta
                    If ColumnasGrilla = "" Then
                        camposConsulta = " tp.* "
                    Else
                        camposConsulta = ""
                        Dim sep As String = ""
                        aux = ColumnasGrilla.Split(",")
                        For Each campos As String In aux
                            If campos Is isPrimaryKey(tablaPrincipal.TableName) Then
                                flagPK = True
                            End If
                            camposConsulta &= sep & "tp." & campos
                            sep = ", "
                        Next
                        If flagPK = False Then
                            Dim camposPk As String = ""
                            For Each pk In isPrimaryKey(tablaPrincipal.TableName)
                                camposPk &= "tp." & pk & ", "
                            Next
                            camposConsulta = camposPk & camposConsulta
                        End If
                    End If

                    'Refrescamos la grilla de datos
                    Lnk_dataset.Clear()
                    Lnk_dataset = DA.Sql.Select(ConnectionString, camposConsulta, tablaPrincipal.TableName & " AS tp")
                    'Agregamos los Nombres de campos customizados al dataset, para las cabeceras de la grilla
                    If AliasCampos IsNot Nothing Then
                        For i = 0 To Lnk_dataset.Tables(0).Columns.Count - 1
                            If AliasCampos(Lnk_dataset.Tables(0).Columns(i).ColumnName) IsNot Nothing Then
                                Lnk_dataset.Tables(0).Columns(i).ColumnName = AliasCampos(Lnk_dataset.Tables(0).Columns(i).ColumnName)
                            End If
                        Next
                    End If
                    tablaDatos.DataSource = Lnk_dataset
                    tablaDatos.DataBind()
                    ViewState.Add("tablaDatosDataSource", Lnk_dataset.Tables(0))

                    tablaDatos.SelectedIndex = -1

                    'Nos movemos de solapas
                    TabContainer1.ActiveTab = TabPanel1
                    menuTab1.Style(HtmlTextWriterStyle.Display) = ""
                    menuTab2.Style(HtmlTextWriterStyle.Display) = "none"

                    'Restaura valor por defecto de variable publica
                    Confirma = False
                End If

            Catch ex As Exception
                Dim fkerror As String = Me.GetFKerror(ex)
                If fkerror Is Nothing Then
                    fkerror = Me.GetTFKerror(ex)
                End If
                If fkerror Is Nothing Then
                    fkerror = Me.GetCFKerror(ex)
                End If
                If fkerror Is Nothing Then
                    fkerror = Me.GetTRFerror(ex)
                End If
                If fkerror Is Nothing AndAlso ex.Message Like "*datos fueron modificados*" Then
                    fkerror = "El registro que Ud. está intentando grabar fue MODIFICADO, por lo que no puede grabar los cambios."
                End If
                If fkerror Is Nothing Then
                    fkerror = ex.Message
                End If

                divErroresEdicion.InnerHtml = fkerror

                'Restaura valor por defecto de variable publica
                Confirma = False
            End Try
        Else
            ModalPopupExtender1.Show()
        End If

    End Sub

    ''' <summary>
    ''' Dispone el abm para editar el registro seleccionado.
    ''' </summary>
    Protected Sub Editar() Handles cmdEdit.Click
        Dim ds As New DataSet
        Dim nombretabla As String
        Dim columnaCant As Integer
        Dim columnaActual As DataColumn
        Dim campoText As String

        lnk_EsUnAlta = False
        nombretabla = Lnk_dataset.Tables(0).TableName
        columnaCant = Lnk_dataset.Tables(0).Columns.Count

        If tablaDatos.SelectedIndex <> -1 Then

            Dim idRegSeleccionado As New ArrayList()
            Dim conta As Integer = 1
            Dim condicion As String = ""
            Dim conector As String = ""
            For Each pk In isPrimaryKey(nombretabla)
                condicion &= conector & Lnk_dataset.Tables(0).Columns(conta - 1).ColumnName & " = '" & tablaDatos.SelectedRow.Cells(conta).Text & "'"
                conector = " AND "
                conta += 1
            Next
            ds = StartFrame.DA.Sql.Select(ConnectionString, "*", nombretabla, condicion)

            For x = 1 To columnaCant
                columnaActual = Lnk_dataset.Tables(0).Columns(x - 1)
                campoText = ds.Tables(0).Rows(0)(x - 1).ToString
                setValorControl(columnaActual.ColumnName, campoText, True)
            Next

            'Disparo evento Display
            RaiseEvent Display()

            'Foco de las solapas
            TabContainer1.ActiveTab = TabPanel2
            menuTab1.Style(HtmlTextWriterStyle.Display) = "none"
            menuTab2.Style(HtmlTextWriterStyle.Display) = ""

            habilitarControles("Filtrado", False)
            habilitarControles("Edicion", True)
            Session("Estado") = "Modificacion"

            'Disparo evento Editando
            RaiseEvent Editando()

        Else
            ModalPopupExtender3.Show()
        End If


    End Sub

    ''' <summary>
    ''' Dispone el abm para insertar un nuevo registro.
    ''' </summary>
    Protected Sub Agregar() Handles cmdAdd.Click
        Dim nombretabla As String
        Dim columnaCant As Integer
        Dim columnaActual As DataColumn

        lnk_EsUnAlta = True
        nombretabla = Lnk_dataset.Tables(0).TableName
        columnaCant = Lnk_dataset.Tables(0).Columns.Count

        For x = 1 To columnaCant
            columnaActual = Lnk_dataset.Tables(0).Columns(x - 1)
            setValorControl(columnaActual.ColumnName, "")
        Next

        TabContainer1.ActiveTab = TabPanel2
        menuTab1.Style(HtmlTextWriterStyle.Display) = "none"
        menuTab2.Style(HtmlTextWriterStyle.Display) = ""
        Session("Estado") = "Alta"

        'Displaro el evento Editando
        RaiseEvent Editando()

        habilitarControles("Filtrado", False)
        habilitarControles("Edicion", True)
    End Sub

    ''' <summary>
    ''' Confirma los cambios ante un alta o modificación y graba el registro.
    ''' </summary>
    Protected Sub Grabar() Handles cmdSave.Click
        Dim tablaPrincipal As DataTable
        Dim columnaCant As Integer
        Dim columnaActual As DataColumn
        Dim consultaCampos As String = ""
        Dim nombreCampos As String = ""
        Dim valorCampos As String = ""
        Dim camposConsulta As String
        Dim aux As String()
        Dim flagPk As Boolean = False
        Dim dsDatos As DataSet
        Dim cancela As Boolean = False
        Dim sErrores As String = ""

        Try
            'Dispara el evento antes de iniciar la grabación
            RaiseEvent Actualizando(cancela)

            If Not cancela Then

                'Obtenemos la informacion necesaria de la tabla con la cual trabajaremos
                tablaPrincipal = Lnk_dataset.Tables(0)
                columnaCant = Lnk_dataset.Tables(0).Columns.Count

                If Session("Estado").ToString = "Alta" Then
                    'Alta de un nuevo registro
                    Dim nuevoRegistro As DataRow = Lnk_dataset.Tables(0).NewRow()

                    For x = 1 To columnaCant
                        columnaActual = Lnk_dataset.Tables(0).Columns(x - 1)
                        valorCampos = obtenerValorControl(columnaActual.ColumnName)
                        If columnaActual.DataType.Name = "Boolean" Then 'Comportamiento para Booleanos
                            If valorCampos = "1" Then
                                nuevoRegistro(columnaActual.ColumnName) = 1
                            Else
                                nuevoRegistro(columnaActual.ColumnName) = 0
                            End If
                        ElseIf columnaActual.DataType.Name = "DateTime" Then 'Comportamiento para DateTime
                            If valorCampos Is Nothing Or valorCampos = "" Then
                                nuevoRegistro(columnaActual.ColumnName) = DBNull.Value
                            Else
                                Dim valorFecha As String
                                Try
                                    valorFecha = convertirFecha(valorCampos)
                                    nuevoRegistro(columnaActual.ColumnName) = valorFecha
                                Catch ex As Exception
                                    nuevoRegistro(columnaActual.ColumnName) = DBNull.Value
                                End Try
                            End If
                        Else 'Comportamiento para el resto de los formatos
                            If valorCampos Is Nothing Or valorCampos = "" Then
                                nuevoRegistro(columnaActual.ColumnName) = DBNull.Value
                            Else
                                nuevoRegistro(columnaActual.ColumnName) = valorCampos
                            End If
                        End If
                    Next

                    Lnk_dataset.Tables(0).Rows.Add(nuevoRegistro)

                ElseIf Session("Estado").ToString = "Modificacion" Then
                    'Modificacion de un registro seleccionado
                    Dim idRegSeleccionado As New ArrayList()
                    Dim conta As Integer = 1

                    'Determina la clave primaria
                    For Each pk In isPrimaryKey(tablaPrincipal.TableName)
                        idRegSeleccionado.Add(tablaDatos.SelectedRow.Cells(conta).Text)
                        conta += 1
                    Next

                    Lnk_dataset.Clear()
                    Dim condicion As String = ""
                    Dim conector As String = ""
                    conta = 0
                    For Each pk In isPrimaryKey(tablaPrincipal.TableName)
                        condicion &= conector & pk & " = '" & idRegSeleccionado(conta) & "'"
                        conector = " and "
                        conta += 1
                    Next
                    Lnk_dataset = StartFrame.DA.Sql.Select(ConnectionString, "*", tablaPrincipal.TableName, condicion)

                    For x = 1 To columnaCant
                        columnaActual = Lnk_dataset.Tables(0).Columns(x - 1)
                        valorCampos = obtenerValorControl(columnaActual.ColumnName)
                        If columnaActual.DataType.Name = "Boolean" Then 'Comportamiento para Booleanos
                            If valorCampos = "1" Then
                                Lnk_dataset.Tables(0).Rows(0)(columnaActual.ColumnName) = 1
                            Else
                                Lnk_dataset.Tables(0).Rows(0)(columnaActual.ColumnName) = 0
                            End If
                        ElseIf columnaActual.DataType.Name = "DateTime" Then 'Comportamiento para DateTime
                            If valorCampos Is Nothing Then
                                Lnk_dataset.Tables(0).Rows(0)(columnaActual.ColumnName) = DBNull.Value
                            Else
                                Dim valorFecha As String
                                Try
                                    valorFecha = convertirFecha(valorCampos)
                                    Lnk_dataset.Tables(0).Rows(0)(columnaActual.ColumnName) = valorFecha
                                Catch ex As Exception
                                    Lnk_dataset.Tables(0).Rows(0)(columnaActual.ColumnName) = DBNull.Value
                                End Try
                            End If
                        Else
                            If valorCampos Is Nothing Then
                                Lnk_dataset.Tables(0).Rows(0)(columnaActual.ColumnName) = DBNull.Value
                            Else
                                Lnk_dataset.Tables(0).Rows(0)(columnaActual.ColumnName) = valorCampos
                            End If
                        End If
                    Next
                End If

                'Se prepara el dataset auxiliar para ejecutar los cambios en la base
                dsDatos = Lnk_dataset.GetChanges()
                Dim bErrores As Boolean = False

                If dsDatos Is Nothing Then
                    Lnk_dataset.RejectChanges()
                Else
                    If dsDatos.Tables(0).HasErrors Then
                        divErroresEdicion.InnerHtml = "Ocurrio un error grabando datos, intentelo nuevamente"
                    Else
                        'Dispara el evento previo a grabar los cambios
                        RaiseEvent CompletarDatos(dsDatos)

                        'Graba utilizando el objeto de negocios
                        ObjetoReglaNegocios.setOperadorLogueado(Operador)
                        ObjetoReglaNegocios.ActualizarDatos(dsDatos)

                        If dsDatos.HasErrors Then
                            'Errores de grabación
                            bErrores = True
                            sErrores = ""

                            'Tratamiento de errores al grabar
                            Dim arrayDataColumn() As DataColumn
                            '...recorre cada tabla del dataset
                            For Each dt As DataTable In dsDatos.Tables
                                If dt.HasErrors Then
                                    '...recorre cada registro de una tabla con errores
                                    For Each dr As DataRow In dt.Rows
                                        arrayDataColumn = dr.GetColumnsInError
                                        '...recorre cada columna para buscar el error
                                        For i As Integer = 0 To arrayDataColumn.Length - 1
                                            sErrores &= dr.GetColumnError(arrayDataColumn(i).ColumnName) & "<br/>"
                                        Next
                                    Next
                                End If
                            Next
                            If sErrores <> String.Empty Then
                                divErroresEdicion.InnerHtml = sErrores
                            End If

                        Else
                            'Dispara el evento posterior a la grabación
                            RaiseEvent Actualizado()

                            'Limpia los controles de pantalla
                            LimpiarControlesFormularioEdicion()
                        End If
                    End If
                End If


                If Not bErrores Then
                    'Obtenemos los campos de la consulta
                    If ColumnasGrilla = "" Then
                        camposConsulta = " tp.* "
                    Else
                        camposConsulta = ""
                        Dim sep As String = ""
                        aux = ColumnasGrilla.Split(",")
                        For Each campos As String In aux
                            If campos Is isPrimaryKey(tablaPrincipal.TableName) Then
                                flagPk = True
                            End If
                            camposConsulta &= sep & "tp." & campos
                            sep = ", "
                        Next
                        If flagPk = False Then
                            Dim camposPk As String = ""
                            For Each pk In isPrimaryKey(tablaPrincipal.TableName)
                                camposPk &= "tp." & pk & ", "
                            Next
                            camposConsulta = camposPk & camposConsulta
                        End If
                    End If

                    'Refrescamos la grilla de datos
                    Lnk_dataset.Clear()
                    Lnk_dataset = DA.Sql.Select(ConnectionString, camposConsulta, tablaPrincipal.TableName & " AS tp")
                    'Agregamos los Nombres de campos customizados al dataset, para las cabeceras de la grilla
                    If AliasCampos IsNot Nothing Then
                        For i = 0 To Lnk_dataset.Tables(0).Columns.Count - 1
                            If AliasCampos(Lnk_dataset.Tables(0).Columns(i).ColumnName) IsNot Nothing Then
                                Lnk_dataset.Tables(0).Columns(i).ColumnName = AliasCampos(Lnk_dataset.Tables(0).Columns(i).ColumnName)
                            End If
                        Next
                    End If
                    tablaDatos.DataSource = Lnk_dataset
                    tablaDatos.DataBind()
                    ViewState.Add("tablaDatosDataSource", Lnk_dataset.Tables(0))
                    tablaDatos.SelectedIndex = -1

                    'Activamos los controles de filtro y  cambiamos de solapa
                    TabContainer1.ActiveTab = TabPanel1
                    menuTab1.Style(HtmlTextWriterStyle.Display) = ""
                    menuTab2.Style(HtmlTextWriterStyle.Display) = "none"

                    Session("Estado") = "Consulta"

                    habilitarControles("Filtrado", True)
                    habilitarControles("Edicion", False)
                End If
            Else
                'Se abortó la grabación por alguna validación.
                ModalPopupExtender5.Show()
            End If

        Catch ex As Exception
            Dim fkerror As String = Me.GetFKerror(ex)
            If fkerror Is Nothing Then
                fkerror = Me.GetTFKerror(ex)
            End If
            If fkerror Is Nothing Then
                fkerror = Me.GetCFKerror(ex)
            End If
            If fkerror Is Nothing Then
                fkerror = Me.GetTRFerror(ex)
            End If
            If fkerror Is Nothing AndAlso ex.Message Like "*datos fueron modificados*" Then
                fkerror = "El registro que Ud. está intentando grabar fue MODIFICADO, por lo que no puede grabar los cambios."
            End If
            If fkerror Is Nothing Then
                fkerror = ex.Message
            End If
            divErroresEdicion.InnerHtml = fkerror
        End Try
    End Sub

    ''' <summary>
    ''' Cancela una edición de un registro (alta o modificación) revirtiendo los cambios.
    ''' </summary>
    Protected Sub Cancelar() Handles cmdCancel.Click

        Try
            If Not Confirma Then
                'Carteles (Msgbox) de confirmacion
                If Session("Estado").ToString = "Modificacion" Then
                    ModalPopupExtender4.Show()
                Else 'Grabacion
                    ModalPopupExtender6.Show()
                End If
            Else
                'Desselecicono el registro de la grilla
                tablaDatos.SelectedIndex = -1
                'Limpio los controles del formulario
                LimpiarControlesFormularioEdicion()

                'Si el estado es de modificaicon se dispara el evento Display
                If Session("Estado").ToString = "Modificacion" Then
                    RaiseEvent Display()
                End If

                'Cambio los tabs
                TabContainer1.ActiveTab = TabPanel1
                menuTab1.Style(HtmlTextWriterStyle.Display) = ""
                menuTab2.Style(HtmlTextWriterStyle.Display) = "none"
                'Habilito y desabilito controles correspondientes
                habilitarControles("Filtrado", True)
                habilitarControles("Edicion", False)
                'Seteo la variable de sesion que indica el estado del AbmBase
                Session("Estado") = "Consulta"

                'Restaura valor por defecto de variable publica
                Confirma = False

            End If
        Catch ex As Exception
            'Restaura valor por defecto de variable publica
            Confirma = False
        End Try
    End Sub

    ''' <summary>
    ''' Llama a la pagina de de ayuda.
    ''' </summary>
    Protected Sub Ayuda() Handles cmdAyuda.Click

    End Sub

    ''' <summary>
    ''' Exporta todos los registros de la grilla de resultados a un formato de libro Excel.
    ''' </summary>
    Protected Sub Exportar() Handles cmdExport.Click
        Dim Response As System.Web.HttpResponse = System.Web.HttpContext.Current.Response

        'Borra la respuesta
        Response.Clear()
        Response.ClearContent()
        Response.ClearHeaders()

        Response.Charset = ""
        Response.ContentType = "application/vnd.ms-excel"
        Response.AddFileDependency("grilla.xls")
        Dim stringWrite As New System.IO.StringWriter
        Dim htmlWrite As New System.Web.UI.HtmlTextWriter(stringWrite)
        Dim dg As New DataGrid
        'dg.DataSource = Lnk_dataset.Tables(0)
        dg.DataSource = ViewState("tablaDatosDataSource")
        dg.DataBind()
        dg.RenderControl(htmlWrite)
        Response.Write(stringWrite.ToString)
        Response.End()
    End Sub

    Protected Sub tablaDatos_Sorting(ByVal sender As Object, ByVal e As GridViewSortEventArgs) Handles tablaDatos.Sorting
        Dim dataTable As DataTable = CType(ViewState("tablaDatosDataSource"), DataTable)

        If Not dataTable Is Nothing Then
            Dim dataView As DataView = New DataView(dataTable)
            dataView.Sort = e.SortExpression + " " + GetSortDirection(e.SortExpression)
            If SortDirection = "ASC" Then
                e.SortDirection = WebControls.SortDirection.Ascending
            ElseIf SortDirection = "DESC" Then
                e.SortDirection = WebControls.SortDirection.Descending
            End If
            SortExpression = e.SortExpression
            tablaDatos.DataSource = dataView
            tablaDatos.DataBind()
            ViewState.Add("tablaDatosDataSource", dataView.Table())
        End If
    End Sub

    Protected Sub tablaDatos_PageIndexChanging(ByVal sender As Object, ByVal e As GridViewPageEventArgs) Handles tablaDatos.PageIndexChanging
        Dim dataTable As DataTable = CType(ViewState("tablaDatosDataSource"), DataTable)
        If Not dataTable Is Nothing Then
            Dim dataView As DataView = New DataView(dataTable)
            tablaDatos.DataSource = dataView
            tablaDatos.PageIndex = e.NewPageIndex
            tablaDatos.DataBind()
            ViewState.Add("tablaDatosDataSource", dataView.Table())
        End If
    End Sub

    Protected Sub tablaDatos_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs) Handles tablaDatos.SelectedIndexChanged
        Dim ds As New DataSet
        Dim nombretabla As String
        Dim columnaCant As Integer
        Dim columnaActual As DataColumn
        Dim campoText As String

        nombretabla = Lnk_dataset.Tables(0).TableName
        columnaCant = Lnk_dataset.Tables(0).Columns.Count

        If tablaDatos.SelectedIndex <> -1 Then

            Try
                Dim idRegSeleccionado As New ArrayList()
                Dim conta As Integer = 1
                Dim condicion As String = ""
                Dim conector As String = ""
                For Each pk In isPrimaryKey(nombretabla)
                    condicion &= conector & Lnk_dataset.Tables(0).Columns(conta - 1).ColumnName & " = '" & tablaDatos.SelectedRow.Cells(conta).Text & "'"
                    conector = " AND "
                    conta += 1
                Next
                ds = StartFrame.DA.Sql.Select(ConnectionString, "*", nombretabla, condicion)

                If SystemFunctions.Files.IsEmpty(ds) Then
                    MsgBox(String.Format("No se pudo seleccionar el registro que cumpla la condición:{0}'{1}'", vbCrLf, condicion), _
                        MsgBoxStyle.Critical + MsgBoxStyle.OkOnly)
                Else
                    For x = 1 To columnaCant
                        columnaActual = Lnk_dataset.Tables(0).Columns(x - 1)
                        campoText = ds.Tables(0).Rows(0)(x - 1).ToString
                        setValorControl(columnaActual.ColumnName, campoText)
                    Next
                End If

                'Foco de las solapas
                TabContainer1.ActiveTab = TabPanel2

            Catch ex As Exception
                MsgBox(String.Format("Se produjo un error al intentar acceder al registro.{0}Error: {1}", vbCrLf, ex.Message), _
                       MsgBoxStyle.Critical + MsgBoxStyle.OkOnly)
            End Try
        End If
    End Sub

    'Boton ACEPTAR de ModalPopupExtender2
    Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
        Confirma = True
        Eliminar()
    End Sub

    'Boton ACEPTAR de ModalPopupExtender4
    Protected Sub Button5_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button5.Click
        Confirma = True
        Cancelar()
    End Sub

    'Boton ACEPTAR de ModalPopupExtender6
    Protected Sub Button8_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button8.Click
        Confirma = True
        Cancelar()
    End Sub

#End Region

#Region "Metodos Publicos"

    ''' <summary>
    ''' Evento principal de inicialización del abm, al cual se le pasa como parámetro una instancia del objeto de reglas del negocio con el cual se lo decide enlazar.
    ''' </summary>
    ''' <remarks>Dicho objeto de reglas del negocio determinará el nivel de seguridad de la página, la entidad contra la cual bindea y las validaciones que deberá pasar.</remarks>
    ''' <param name="obr">Instancia del objeto de reglas del negocio que se encargará de la lógica de negocios del abm.</param>
    Public Sub InicializarPagina(ByVal obr As IAbm)
        Dim tablaEdicion As New Table

        'TabVisible
        TabPanel3.Visible = (TabsAdicionales >= 1)
        TabPanel4.Visible = (TabsAdicionales >= 2)
        TabPanel5.Visible = (TabsAdicionales >= 3)
        TabPanel6.Visible = (TabsAdicionales >= 4)
        TabPanel7.Visible = (TabsAdicionales >= 5)
        TabPanel8.Visible = (TabsAdicionales >= 6)
        TabPanel9.Visible = (TabsAdicionales >= 7)
        TabPanel10.Visible = (TabsAdicionales >= 8)

        'Título de los tabs
        TabPanel3.HeaderText = lblTabs
        TabPanel4.HeaderText = lblTabs1
        TabPanel5.HeaderText = lblTabs2
        TabPanel6.HeaderText = lblTabs3
        TabPanel7.HeaderText = lblTabs4
        TabPanel8.HeaderText = lblTabs5
        TabPanel9.HeaderText = lblTabs6
        TabPanel10.HeaderText = lblTabs7

        'Titulo del ABM
        abmTitulo1.InnerText = lblTitulo

        'Objeto de regla de negocios
        ObjetoReglaNegocios = obr
        ObjetoReglaNegocios.setOperadorLogueado(Common.Env.Operador)

        'Obtenemos Dataset
        Lnk_dataset = ObjetoReglaNegocios.getDataSet

        'Seteamos la propiedad de tabla principal
        TablaPrincipal = Lnk_dataset.Tables(0).TableName

        'Campos de filtrado
        tablaFiltrado = TablaFormulario(Lnk_dataset, FiltrosBusqueda, "filtro", True)
        divFiltro.Controls.Add(tablaFiltrado)

        'Campos de edicion
        If CamposEdicion <> "" Then
            If FormularioEdicion.Controls.Count > 1 Then
                If Not FormularioEdicion.Controls(1) Is Nothing Then
                    For x = 1 To FormularioEdicion.Controls.Count - 1
                        Dim ctrl As Control
                        ctrl = FormularioEdicion.Controls(1)
                        FormularioEdicion.Controls.Remove(ctrl)
                        'FormularioEdicion.Controls.Remove(CType(FormularioEdicion.Controls(1), Panel))
                    Next
                End If
            End If
            Dim panelEdicion As New Panel
            panelEdicion.Controls.Add(TablaFormulario(Lnk_dataset, CamposEdicion, "", True))
            FormularioEdicionAuto.Controls.Add(panelEdicion)
        End If

        ViewState.Add("camposFk", camposFK)

        If Not Page.IsPostBack Then
            Session("Estado") = Nothing
        End If

        'Estado de controles
        If Session("Estado") IsNot Nothing Then
            If Session("Estado").ToString = "Alta" Or Session("Estado").ToString = "Modificacion" Then
                habilitarControles("Filtrado", False)
                habilitarControles("Edicion", True)
            Else
                habilitarControles("Filtrado", True)
                habilitarControles("Edicion", False)
            End If
        Else
            habilitarControles("Filtrado", True)
            habilitarControles("Edicion", False)
        End If

        'Alta/Baja/Modi
        Me.cmdAdd.Visible = _AltasOk
        Me.cmdDelete.Visible = _BajasOk
        Me.cmdEdit.Visible = _ModifOk
    End Sub

    'Obtiene el valor de un control por id
    Public Function obtenerValorControl(ByVal controlId As String) As String
        Dim tipoControl As String
        Dim valor As String = Nothing
        Dim formulario As New ContentPlaceHolder
        Dim ctrl As System.Web.UI.Control = Nothing

        'Busca el control dentro de la página
        ctrl = ObtenerControl(controlId)

        If Not ctrl Is Nothing Then
            tipoControl = ctrl.GetType.Name()

            Select Case tipoControl
                Case "TextBox"
                    Dim mpControl As TextBox
                    mpControl = CType(ctrl, TextBox)
                    If Not mpControl Is Nothing Then
                        valor = mpControl.Text
                    Else
                        valor = Nothing
                    End If

                Case "DropDownList"
                    Dim mpControl As DropDownList
                    mpControl = CType(ctrl, DropDownList)
                    If Not mpControl Is Nothing Then
                        If Not mpControl.SelectedItem Is Nothing Then
                            valor = mpControl.SelectedItem.Value
                        Else
                            valor = Nothing
                        End If
                    Else
                        valor = Nothing

                    End If
                Case "CheckBox"
                    Dim mpControl As CheckBox
                    mpControl = CType(ctrl, CheckBox)
                    If mpControl.Checked Then
                        valor = "1"
                    Else
                        valor = "0"
                    End If
                Case "RadioButtonList"
                    Dim mpControl As RadioButtonList
                    mpControl = CType(ctrl, RadioButtonList)
                    If Not mpControl Is Nothing Then
                        If Not mpControl.SelectedItem Is Nothing Then
                            valor = mpControl.SelectedItem.Value
                        Else
                            valor = Nothing
                        End If
                    Else
                        valor = Nothing
                    End If
                Case "LNKWebFK"
                    Dim mpLNK As New LNKWebFK
                    mpLNK = CType(ctrl, Webparts.LNKWebFK)
                    If Not mpLNK Is Nothing Then
                        valor = mpLNK.Value
                    Else
                        valor = Nothing
                    End If
            End Select
        Else
            valor = Nothing
        End If

        Return valor

    End Function

#End Region

#Region "Metodos Privados"

    'Arma en runtime las tablas de formularios
    Private Function TablaFormulario(ByVal brDataset As DataSet, ByVal campos As String, ByVal prefix As String, _
                                     ByVal camposPk As Boolean) As Table
        Dim tablaActual As New DataTable
        Dim tablaResultado As New Table
        Dim columnaActual As DataColumn
        Dim flagCf As Boolean = False
        Dim flagTc As Boolean = False
        Dim splitCampos As String() = Nothing

        'Obtengo la tabla a trabajar
        tablaActual = brDataset.Tables(0)

        'Obtengo los primary key de la tabla
        Dim pkColumnas As ArrayList = isPrimaryKey(tablaActual.TableName)

        'Chequeo si la lista de campos a mostrar tiene datos o no
        If campos <> "" Then
            splitCampos = campos.Split(",")
            flagTc = False
        Else
            flagTc = True
        End If

        'Hay lista de campos
        If flagTc = False Then
            For Each campo As String In splitCampos
                campo = campo.Trim
                Try
                    columnaActual = tablaActual.Columns(campo)
                    tablaResultado.Controls.Add(obtenerFilaTablaFormulario(tablaActual, columnaActual, prefix))
                Catch ex As Exception
                End Try
            Next
        Else
            For Each columna In tablaActual.Columns
                columnaActual = columna
                tablaResultado.Controls.Add(obtenerFilaTablaFormulario(tablaActual, columnaActual, prefix))
            Next
        End If

        Return tablaResultado

    End Function

    'Crea las filas con controles para la tabla del formulario
    Private Function obtenerFilaTablaFormulario(ByVal tablaActual As DataTable, ByVal columnaActual As DataColumn, ByVal prefix As String) As TableRow
        Dim tipoColumna As String
        Dim prefixfecha As String
        Dim salto As New Literal

        tipoColumna = columnaActual.DataType.Name

        Dim tr As New TableRow

        'Etiqueta del campo
        Dim cLabel As New Label
        If AliasCampos IsNot Nothing Then
            If AliasCampos(columnaActual.ColumnName) IsNot Nothing Then
                cLabel.Text = AliasCampos(columnaActual.ColumnName) & "&nbsp;:"
            Else
                cLabel.Text = columnaActual.ColumnName & "&nbsp;:"
            End If
        Else
            cLabel.Text = columnaActual.ColumnName & "&nbsp;:"
        End If

        Dim tdE As New TableCell
        tdE.Controls.Add(cLabel)
        tdE.HorizontalAlign = HorizontalAlign.Right
        tr.Controls.Add(tdE)

        'Tipo de dato y campo a completar y validacion
        Dim tdC As New TableCell

        If isForeingKey(tablaActual.TableName, columnaActual.ColumnName) <> "" Then
            'Checkeo de que CamposForeignKey no este vacio
            If Not CamposForeingKey Is Nothing Then
                If Not CamposForeingKey(columnaActual.ColumnName) Is Nothing Then
                    Dim ds As DataSet
                    Dim fkTabla As String = isForeingKey(tablaActual.TableName, columnaActual.ColumnName)
                    Dim fkCampo As String = isPrimaryKey(fkTabla)(0)
                    Dim cSelect As New DropDownList
                    Dim datosFk As String()
                    Dim campoFk1, campoFk2, tablaFk As String

                    If prefix <> "" Then
                        cSelect.ID = prefix & "_" & columnaActual.ColumnName()
                    Else
                        cSelect.ID = columnaActual.ColumnName()
                    End If

                    Try
                        datosFk = CamposForeingKey(columnaActual.ColumnName).ToString.Split(",")
                        campoFk1 = datosFk(1)
                        campoFk2 = datosFk(2)
                        tablaFk = datosFk(0)
                        Try
                            ds = StartFrame.DA.Sql.Select(ConnectionString, "distinct " & campoFk1 & ", " & campoFk2, fkTabla)
                        Catch ex As Exception
                            ds = StartFrame.DA.Sql.Select(ConnectionString, campoFk1 & ", " & campoFk2, fkTabla)
                        End Try

                        If ds.Tables(0).Rows.Count > 0 Then
                            For i = 0 To ds.Tables(0).Rows.Count - 1
                                Dim fkValor As String = ds.Tables(0).Rows(i)(fkCampo)
                                Dim fkTexto As String = ds.Tables(0).Rows(i)(1)
                                Dim csItem As New ListItem
                                csItem.Value = fkValor
                                csItem.Text = fkTexto
                                cSelect.Items.Add(csItem)
                            Next
                            If prefix <> "" Then
                                Dim csItemAll As New ListItem
                                csItemAll.Text = "Todos"
                                csItemAll.Value = ""
                                csItemAll.Selected = True
                                cSelect.Items.Add(csItemAll)
                            End If

                            cSelect.Attributes.Add("class", "sel")

                            tdC.Controls.Add(cSelect)
                        End If
                    Catch
                        Dim control As New TextBox
                        If prefix <> "" Then
                            control.ID = prefix & "_" & columnaActual.ColumnName()
                        Else
                            control.ID = columnaActual.ColumnName()
                        End If
                        control.Attributes.Add("class", "texto")
                        tdC.Controls.Add(control)
                    End Try
                Else
                    Dim control As New TextBox
                    If prefix <> "" Then
                        control.ID = prefix & "_" & columnaActual.ColumnName()
                    Else
                        control.ID = columnaActual.ColumnName()
                    End If
                    control.Attributes.Add("class", "texto")
                    tdC.Controls.Add(control)
                End If
            Else
                Dim control As New TextBox
                If prefix <> "" Then
                    control.ID = prefix & "_" & columnaActual.ColumnName()
                Else
                    control.ID = columnaActual.ColumnName()
                End If
                control.Attributes.Add("class", "texto")
                tdC.Controls.Add(control)
            End If

        Else
            Dim validador As New CompareValidator
            validador.Operator = ValidationCompareOperator.DataTypeCheck
            If prefix <> "" Then
                validador.ID = "fcv_" & columnaActual.ColumnName()
            Else
                validador.ID = "cv_" & columnaActual.ColumnName()
            End If
            If prefix <> "" Then
                validador.ControlToValidate = prefix & "_" & columnaActual.ColumnName()
            Else
                validador.ControlToValidate = columnaActual.ColumnName()
            End If

            Select Case tipoColumna
                Case "String"
                    Dim cTxtBox As New TextBox

                    If prefix <> "" Then
                        cTxtBox.ID = prefix & "_" & columnaActual.ColumnName()
                    Else
                        cTxtBox.ID = columnaActual.ColumnName()
                    End If

                    cTxtBox.Attributes.Add("class", "texto")

                    tdC.Controls.Add(cTxtBox)
                Case "DateTime"
                    prefixfecha = ""
                    For z = 0 To 1
                        'Esta condicion supone que si prefix es vacio, se esta intentando crear el control de fecha de la segunda solapa, por eso ignora el segundo control
                        If z = 0 Or (z = 1 And prefix <> "") Then
                            Dim cDateTime As New TextBox
                            Dim cCalendar As New AjaxControlToolkit.CalendarExtender
                            Dim cCalendarImage As New Image
                            Dim espacio As New Literal

                            If prefix <> "" Then
                                cDateTime.ID = prefix & "_" & prefixfecha & columnaActual.ColumnName()
                            Else
                                cDateTime.ID = columnaActual.ColumnName()
                            End If

                            cDateTime.Attributes.Add("class", "texto")

                            cCalendar.Format = "dd-MM-yyyy hh:mm:ss"
                            cCalendarImage.ImageUrl = "../App_img/calendar.gif"
                            cCalendarImage.ID = "calendarImg" & z
                            cCalendarImage.Style.Add("cursor", "pointer")
                            espacio.Text = "&nbsp;"

                            If prefix <> "" Then
                                cCalendar.TargetControlID = prefix & "_" & prefixfecha & columnaActual.ColumnName()
                            Else
                                cCalendar.TargetControlID = columnaActual.ColumnName()
                            End If

                            cCalendar.PopupButtonID = cCalendarImage.ID
                            cCalendar.Enabled = True
                            tdC.Controls.Add(cDateTime)
                            tdC.Controls.Add(espacio)
                            tdC.Controls.Add(cCalendarImage)
                            tdC.Controls.Add(cCalendar)
                        End If

                        'Como la fecha maneja dos campos diferentes la validacion debe ser alterada
                        If z = 0 Then
                            Dim espacio As New Literal
                            espacio.Text = "&nbsp;"
                            If prefix <> "" Then
                                'validador.ID = "fcv_" & columnaActual.ColumnName() & z
                                'validador.ControlToValidate = prefix & "_" & prefixfecha & columnaActual.ColumnName()
                            Else
                                'validador.ID = "cv_" & columnaActual.ColumnName() & z
                                'validador.ControlToValidate = prefixfecha & columnaActual.ColumnName()
                            End If
                            'validador.ErrorMessage = "Solo valores de fecha"
                            'validador.Type = ValidationDataType.Date
                            'tdC.Controls.Add(validador)
                            tdC.Controls.Add(espacio)
                            prefixfecha = "hasta_"
                            salto.Text = "<br/>"
                            tdC.Controls.Add(salto)
                        ElseIf z = 1 And prefix <> "" Then
                            Dim espacio As New Literal
                            espacio.Text = "&nbsp;"
                            'Dim validador2 As New CompareValidator
                            'validador2.Operator = ValidationCompareOperator.DataTypeCheck
                            If prefix <> "" Then
                                'validador2.ID = "fcv_" & columnaActual.ColumnName() & z
                                'validador2.ControlToValidate = prefix & "_" & prefixfecha & columnaActual.ColumnName()
                            Else
                                'validador2.ID = "cv_" & columnaActual.ColumnName() & z
                                'validador2.ControlToValidate = prefixfecha & columnaActual.ColumnName()
                            End If
                            'validador2.ErrorMessage = "Solo valores de fecha"
                            'validador2.Type = ValidationDataType.Date
                            'tdC.Controls.Add(validador2)
                            tdC.Controls.Add(espacio)
                        End If
                    Next
                Case "Date"
                    prefixfecha = ""
                    For z = 0 To 1
                        'Esta condicion supone que si prefix es vacio, se esta intentando crear el control de fecha de la segunda solapa, por eso ignora el segundo control
                        If z = 0 Or (z = 1 And prefix <> "") Then
                            Dim cDateTime As New TextBox
                            Dim cCalendar As New AjaxControlToolkit.CalendarExtender
                            Dim cCalendarImage As New Image
                            Dim espacio As New Literal

                            If prefix <> "" Then
                                cDateTime.ID = prefix & "_" & prefixfecha & columnaActual.ColumnName()
                            Else
                                cDateTime.ID = columnaActual.ColumnName()
                            End If

                            cDateTime.Attributes.Add("class", "texto")

                            cCalendar.Format = "dd-MM-yyyy"
                            cCalendarImage.ImageUrl = "../App_img/calendar.gif"
                            cCalendarImage.ID = "calendarImg" & z
                            cCalendarImage.Style.Add("cursor", "pointer")
                            espacio.Text = "&nbsp;"

                            If prefix <> "" Then
                                cCalendar.TargetControlID = prefix & "_" & prefixfecha & columnaActual.ColumnName()
                            Else
                                cCalendar.TargetControlID = columnaActual.ColumnName()
                            End If

                            cCalendar.PopupButtonID = cCalendarImage.ID
                            cCalendar.Enabled = True
                            tdC.Controls.Add(cDateTime)
                            tdC.Controls.Add(espacio)
                            tdC.Controls.Add(cCalendarImage)
                            tdC.Controls.Add(cCalendar)
                        End If

                        'Como la fecha maneja dos campos diferentes la validacion debe ser alterada
                        If z = 0 Then
                            If prefix <> "" Then
                                validador.ID = "fcv_" & columnaActual.ColumnName() & z
                                validador.ControlToValidate = prefix & "_" & prefixfecha & columnaActual.ColumnName()
                            Else
                                validador.ID = "cv_" & columnaActual.ColumnName() & z
                                validador.ControlToValidate = prefixfecha & columnaActual.ColumnName()
                            End If
                            validador.ErrorMessage = "Solo valores de fecha"
                            validador.Type = ValidationDataType.Date
                            tdC.Controls.Add(validador)
                            prefixfecha = "hasta_"
                            salto.Text = "<br/>"
                            tdC.Controls.Add(salto)
                        ElseIf z = 1 And prefix <> "" Then
                            Dim validador2 As New CompareValidator
                            validador2.Operator = ValidationCompareOperator.DataTypeCheck
                            If prefix <> "" Then
                                validador2.ID = "fcv_" & columnaActual.ColumnName() & z
                                validador2.ControlToValidate = prefix & "_" & prefixfecha & columnaActual.ColumnName()
                            Else
                                validador2.ID = "cv_" & columnaActual.ColumnName() & z
                                validador2.ControlToValidate = prefixfecha & columnaActual.ColumnName()
                            End If
                            validador2.ErrorMessage = "Solo valores de fecha"
                            validador2.Type = ValidationDataType.Date
                            tdC.Controls.Add(validador2)
                        End If
                    Next
                Case "Int16", "Int32", "Int65"
                    Dim cIntBox As New TextBox
                    If prefix <> "" Then
                        cIntBox.ID = prefix & "_" & columnaActual.ColumnName()
                    Else
                        cIntBox.ID = columnaActual.ColumnName()
                    End If

                    cIntBox.Attributes.Add("class", "texto")

                    tdC.Controls.Add(cIntBox)
                    validador.ErrorMessage = "Solo valores numericos"
                    validador.Type = ValidationDataType.Integer
                    tdC.Controls.Add(validador)
                Case "Double", "Single"
                    Dim cIntBox As New TextBox
                    If prefix <> "" Then
                        cIntBox.ID = prefix & "_" & columnaActual.ColumnName()
                    Else
                        cIntBox.ID = columnaActual.ColumnName()
                    End If

                    cIntBox.Attributes.Add("class", "texto")

                    tdC.Controls.Add(cIntBox)
                    validador.ErrorMessage = "Solo valores numericos"
                    validador.Type = ValidationDataType.Double
                    tdC.Controls.Add(validador)
                Case "Boolean"
                    Dim cSelect As New DropDownList
                    If prefix <> "" Then
                        cSelect.ID = prefix & "_" & columnaActual.ColumnName()
                    Else
                        cSelect.ID = columnaActual.ColumnName()
                    End If
                    Dim csItem1 As New ListItem
                    csItem1.Value = "1"
                    csItem1.Text = "Si"
                    Dim csItem0 As New ListItem
                    csItem0.Value = "0"
                    csItem0.Text = "No"
                    cSelect.Items.Add(csItem0)
                    cSelect.Items.Add(csItem1)
                    If prefix <> "" Then
                        Dim csItemAll As New ListItem
                        csItemAll.Value = ""
                        csItemAll.Text = "Todos"
                        csItemAll.Selected = True
                        cSelect.Items.Add(csItemAll)
                    End If

                    cSelect.Attributes.Add("class", "sel")

                    tdC.Controls.Add(cSelect)
                Case "Text"
                    Dim cText As New TextBox
                    If prefix <> "" Then
                        cText.ID = prefix & "_" & columnaActual.ColumnName()
                    Else
                        cText.ID = columnaActual.ColumnName()
                    End If

                    cText.Attributes.Add("class", "texto")

                    cText.TextMode = TextBoxMode.MultiLine
                    cText.Height = 100
                    tdC.Controls.Add(cText)
                Case Else
                    Dim cTxtBox As New TextBox

                    If prefix <> "" Then
                        cTxtBox.ID = prefix & "_" & columnaActual.ColumnName()
                    Else
                        cTxtBox.ID = columnaActual.ColumnName()
                    End If

                    cTxtBox.Attributes.Add("class", "texto")

                    tdC.Controls.Add(cTxtBox)
            End Select

        End If

        'label que indica el tipo de dato que es (solo para debug)
        'Dim tipoDato As New Label
        'tipoDato.Text = columnas(x - 1).DataType.ToString
        'tdC.Controls.Add(tipoDato)

        tdC.HorizontalAlign = HorizontalAlign.Left
        tr.Controls.Add(tdC)

        Return tr
    End Function

    'Setea un valor a un control por id
    Private Sub setValorControl(ByVal controlId As String, ByVal contenido As String, Optional ByVal bloquearCamposPK As Boolean = False)
        Dim tipoControl As String
        Dim formulario As New ContentPlaceHolder
        Dim flagHabilitado As Boolean
        Dim ctrl As System.Web.UI.Control = Nothing

        'Busca el control dentro de la página
        ctrl = ObtenerControl(controlId)

        If Not ctrl Is Nothing Then
            tipoControl = ctrl.GetType.Name()

            'En caso de que el campo sea Primary Key y bloquearCamposPK sea True, lo deshabilito para que no sea modifiado
            flagHabilitado = True
            If bloquearCamposPK Then
                Dim camposPk As New ArrayList()
                camposPk = isPrimaryKey(TablaPrincipal)
                For Each campo In camposPk
                    If campo = controlId Then
                        flagHabilitado = False
                    End If
                Next
            End If


            Select Case tipoControl
                Case "TextBox"
                    Dim mpTextBox As TextBox
                    mpTextBox = CType(ctrl, TextBox)
                    If Not mpTextBox Is Nothing Then
                        mpTextBox.Text = contenido
                    End If
                    mpTextBox.Enabled = flagHabilitado

                Case "DropDownList"
                    Dim mpDropDown As DropDownList
                    mpDropDown = CType(ctrl, DropDownList)
                    If Not mpDropDown Is Nothing Then
                        For Each item As ListItem In mpDropDown.Items
                            If item.Value = contenido Then
                                item.Selected = True
                            Else
                                item.Selected = False
                            End If
                        Next
                    End If
                    mpDropDown.Enabled = flagHabilitado

                Case "CheckBox"
                    Dim mpCheckBox As CheckBox
                    mpCheckBox = CType(ctrl, CheckBox)
                    If Not mpCheckBox Is Nothing Then
                        If contenido = "True" Then
                            mpCheckBox.Checked = True
                        Else
                            mpCheckBox.Checked = False
                        End If
                    End If
                    mpCheckBox.Enabled = flagHabilitado

                Case "RadioButtonList"
                    Dim mpRadioButton As RadioButtonList
                    mpRadioButton = CType(ctrl, RadioButtonList)
                    If Not mpRadioButton Is Nothing Then
                        For Each item As ListItem In mpRadioButton.Items
                            If contenido = item.Value Then
                                item.Selected = True
                            End If
                        Next
                    End If
                    mpRadioButton.Enabled = flagHabilitado

                Case "LNKWebFK"
                    Dim mpLNK As New LNKWebFK
                    mpLNK = CType(ctrl, Webparts.LNKWebFK)
                    If Not mpLNK Is Nothing Then
                        Dim ds As New DataSet
                        ds = Sql.Select(ConnectionString, mpLNK.LvDescrip, mpLNK.LvTabla, "WHERE " & mpLNK.LvCampo & " = " & contenido)
                        mpLNK.Value = contenido
                        mpLNK.Texto = ds.Tables(0).Rows(0)(0).ToString
                    End If
                    mpLNK.Enabled = flagHabilitado
            End Select
        End If
    End Sub

    'Retorna un control por su ID
    Private Function ObtenerControl(idControl As String) As System.Web.UI.Control

        Dim formulario As New ContentPlaceHolder
        Dim ctrl As System.Web.UI.Control = Nothing

        If CamposEdicion <> "" Then
            'Abm automático
            formulario = FormularioEdicionAuto
        Else
            'Abm de 1 página
            formulario = FormularioEdicion
        End If

        ctrl = formulario.FindControl(idControl)

        'Abm de n contenedores
        If ctrl Is Nothing Then
            formulario = FormularioEdicion1
            ctrl = formulario.FindControl(idControl)
        End If
        If ctrl Is Nothing Then
            formulario = FormularioEdicion2
            ctrl = formulario.FindControl(idControl)
        End If
        If ctrl Is Nothing Then
            formulario = FormularioEdicion3
            ctrl = formulario.FindControl(idControl)
        End If
        If ctrl Is Nothing Then
            formulario = FormularioEdicion4
            ctrl = formulario.FindControl(idControl)
        End If
        If ctrl Is Nothing Then
            formulario = FormularioEdicion5
            ctrl = formulario.FindControl(idControl)
        End If
        If ctrl Is Nothing Then
            formulario = FormularioEdicion6
            ctrl = formulario.FindControl(idControl)
        End If
        If ctrl Is Nothing Then
            formulario = FormularioEdicion7
            ctrl = formulario.FindControl(idControl)
        End If
        If ctrl Is Nothing Then
            formulario = FormularioEdicion8
            ctrl = formulario.FindControl(idControl)
        End If

        'Retorno
        Return ctrl

    End Function

    'Habilita controles de un formulario
    Private Sub habilitarControles(ByVal opcion As String, ByVal estado As Boolean)
        Dim formulario As New ContentPlaceHolder
        Dim controlNumero As Integer

        If CamposEdicion <> "" Then
            formulario = FormularioEdicionAuto
            controlNumero = 0

        Else
            formulario = FormularioEdicion
            controlNumero = 1
        End If

        If opcion = "Filtrado" Then
            tablaFiltrado.Enabled = estado
        ElseIf opcion = "Edicion" Then
            If Not formulario.Controls(controlNumero) Is Nothing Then
                CType(formulario.Controls(controlNumero), Panel).Enabled = estado
            End If
            If Not CType(FormularioEdicion1.Controls(1), Panel) Is Nothing Then
                CType(FormularioEdicion1.Controls(1), Panel).Enabled = estado
            End If
            If Not CType(FormularioEdicion2.Controls(1), Panel) Is Nothing Then
                CType(FormularioEdicion2.Controls(1), Panel).Enabled = estado
            End If
            If Not CType(FormularioEdicion3.Controls(1), Panel) Is Nothing Then
                CType(FormularioEdicion3.Controls(1), Panel).Enabled = estado
            End If
            If Not CType(FormularioEdicion4.Controls(1), Panel) Is Nothing Then
                CType(FormularioEdicion4.Controls(1), Panel).Enabled = estado
            End If
            If Not CType(FormularioEdicion5.Controls(1), Panel) Is Nothing Then
                CType(FormularioEdicion5.Controls(1), Panel).Enabled = estado
            End If
            If Not CType(FormularioEdicion6.Controls(1), Panel) Is Nothing Then
                CType(FormularioEdicion6.Controls(1), Panel).Enabled = estado
            End If
            If Not CType(FormularioEdicion7.Controls(1), Panel) Is Nothing Then
                CType(FormularioEdicion7.Controls(1), Panel).Enabled = estado
            End If
            If Not CType(FormularioEdicion8.Controls(1), Panel) Is Nothing Then
                CType(FormularioEdicion8.Controls(1), Panel).Enabled = estado
            End If
        End If
    End Sub

    'Convierte formatos de fecha
    Private Function convertirFecha(ByVal fecha As String) As String
        Dim result As String
        If fecha <> "" Then
            Dim supportedFormats() As String = New String() {"ddMMMyyyy", "dMMMyyyy", "dd/MM/yyyy", "dd-MM-yyyy", "ddMMMyyyy hh:mm:ss", "dMMMyyyy hh:mm:ss", "dd/MM/yyyy hh:mm:ss", "dd-MM-yyyy hh:mm:ss"}
            result = DateTime.ParseExact(fecha, supportedFormats, System.Globalization.CultureInfo.CurrentCulture, _
                                         System.Globalization.DateTimeStyles.None).ToString("yyyy/MM/dd")
            Return result
        Else
            Return ""
        End If
    End Function

    'Devuelve los campos primarykey de una tabla
    Private Function isPrimaryKey(ByRef tabla As String) As ArrayList
        Dim ds As DataSet
        Dim conta As Integer = 0
        Dim resultado As New ArrayList()

        Dim qCampos As String = "COLUMN_NAME"
        Dim qTablas As String = "INFORMATION_SCHEMA.KEY_COLUMN_USAGE K, INFORMATION_SCHEMA.TABLE_CONSTRAINTS C"
        Dim qWhere As String = "K.CONSTRAINT_NAME = C.CONSTRAINT_NAME AND K.TABLE_NAME = '" & tabla & "' AND C.CONSTRAINT_TYPE = 'PRIMARY KEY'"
        Dim qOrder As String = "ORDINAL_POSITION ASC"

        ds = StartFrame.DA.Sql.Select(ConnectionString, qCampos, qTablas, qWhere, qOrder)

        For Each x In ds.Tables(0).Rows
            'Return ds.Tables(0).Rows(0)(0)
            resultado.Add(x(0))
        Next

        Return resultado

        If resultado Is Nothing Then
            Return Nothing
        End If

    End Function

    'Valida si un campo de una tabla es foreing key
    Private Function isForeingKey(ByVal tabla As String, ByVal campo As String) As String
        Dim ds As DataSet

        Dim qCampos As String = "PK.TABLE_NAME AS pk_columna"
        Dim qTablas As String = "INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS C, INFORMATION_SCHEMA.TABLE_CONSTRAINTS FK, INFORMATION_SCHEMA.TABLE_CONSTRAINTS PK, INFORMATION_SCHEMA.KEY_COLUMN_USAGE CU"
        Dim qWhere As String = "C.CONSTRAINT_NAME = FK.CONSTRAINT_NAME AND C.UNIQUE_CONSTRAINT_NAME = PK.CONSTRAINT_NAME AND C.CONSTRAINT_NAME = CU.CONSTRAINT_NAME AND FK.TABLE_NAME = '" & tabla & "' AND CU.COLUMN_NAME = '" & campo & "'"

        ds = StartFrame.DA.Sql.Select(ConnectionString, qCampos, qTablas, qWhere)

        If ds.Tables(0).Rows.Count > 0 Then
            Return ds.Tables(0).Rows(0)(0)
        Else
            Return ""
        End If

    End Function

    'Limpia los controles del formulario Edicion
    Private Sub LimpiarControlesFormularioEdicion()
        Dim controlId As String
        Dim tipoControl As String
        Dim formulario As New ContentPlaceHolder
        Dim ctrl As System.Web.UI.Control = Nothing

        For Each columna As DataColumn In Lnk_dataset.Tables(0).Columns
            controlId = columna.ColumnName

            'Busca el control dentro de la página
            ctrl = ObtenerControl(controlId)

            If Not ctrl Is Nothing Then
                tipoControl = ctrl.GetType.Name()
                Select Case tipoControl
                    Case "TextBox"
                        Dim mpTextBox As TextBox
                        mpTextBox = CType(ctrl, TextBox)
                        If Not mpTextBox Is Nothing Then
                            mpTextBox.Text = String.Empty
                        End If
                    Case "DropDownList"
                        Dim mpDropDown As DropDownList
                        mpDropDown = CType(ctrl, DropDownList)
                        If Not mpDropDown Is Nothing Then
                            mpDropDown.SelectedIndex() = 0
                        End If
                    Case "CheckBox"
                        Dim mpCheckBox As CheckBox
                        mpCheckBox = CType(ctrl, CheckBox)
                        If Not mpCheckBox Is Nothing Then
                            mpCheckBox.Checked = False
                        End If
                    Case "RadioButtonList"
                        Dim mpRadioButton As RadioButtonList
                        mpRadioButton = CType(ctrl, RadioButtonList)
                        If Not mpRadioButton Is Nothing Then
                            mpRadioButton.SelectedIndex = 0
                        End If
                    Case "LNKWebFK"
                        Dim mpLNK As New LNKWebFK
                        mpLNK = CType(ctrl, Webparts.LNKWebFK)
                        If Not mpLNK Is Nothing Then
                            mpLNK.Texto = String.Empty
                            mpLNK.Value = String.Empty
                        End If
                End Select
            End If
        Next
    End Sub

    'Rellena los combos relacionados a campos foreing key
    Private Sub setCombosFK(ByVal controlId As String)
        Dim listaIdFk As New ArrayList
        Dim formulario As New ContentPlaceHolder
        Dim ctrl As System.Web.UI.Control = Nothing

        'Busca el control dentro de la página
        ctrl = ObtenerControl(controlId)

        listaIdFk = ViewState("camposFk")
        For Each controlId In listaIdFk
            If Not ctrl Is Nothing Then
                Dim mpControl As DropDownList
                mpControl = CType(ctrl, DropDownList)
                If Not mpControl Is Nothing Then
                    Dim itemcol As New Hashtable
                    itemcol = CType(ViewState(controlId), Hashtable)
                    mpControl.DataSource = itemcol
                    mpControl.DataValueField = "Key"
                    mpControl.DataTextField = "Value"
                    mpControl.DataBind()
                    'mpControl.SelectedValue = ""
                End If
            ElseIf Not divFiltro.FindControl(controlId) Is Nothing Then
                Dim mpControl As DropDownList
                mpControl = CType(divFiltro. _
                        FindControl(controlId), DropDownList)
                If Not mpControl Is Nothing Then
                    Dim itemcol As New Hashtable
                    itemcol = CType(ViewState(controlId), Hashtable)
                    mpControl.DataSource = itemcol
                    mpControl.DataValueField = "Key"
                    mpControl.DataTextField = "Value"
                    mpControl.DataBind()
                    'mpControl.SelectedValue = ""
                End If
            End If
        Next
    End Sub

    'Funcion para el ordenamiento de los campos en la grilla
    Private Function GetSortDirection(ByVal sExpression As String) As String
        If sExpression = SortExpression Then
            If SortDirection = "ASC" Then
                SortDirection = "DESC"
            ElseIf SortDirection = "DESC" Then
                SortDirection = "ASC"
            Else
                SortDirection = "ASC"
            End If
            Return SortDirection
        Else
            SortExpression = SortExpression
            SortDirection = "ASC"
            Return SortDirection
        End If
    End Function

    'Navega en una excepción para determinar si el error es del tipo FK
    Private Function GetFKerror(ByVal ex As Exception) As String

        'Error no identificado
        If ex.Message.IndexOf("COLUMN FOREIGN KEY") = -1 Then
            Return Nothing
        End If

        'Recorre el texto del error y arma el mensaje para el usuario
        Dim myArray() As String = ex.Message.Split(Chr(39))
        Dim nlongitud As Integer = myArray.GetLength(0)
        Dim i As Integer
        Dim nOccurs As Integer = 0
        Dim sRtrn As String = "Error de integridad referencial. "
        'If _dataset.Tables.Count > 1 Then
        '    sRtrn &= "Posiblemente se deba a que no se pudo grabar el registro de la tabla principal debido a otros errores. "
        'End If

        For i = 0 To nlongitud - 1
            If myArray(i).IndexOf("tabla") <> -1 Or myArray(i).IndexOf("table") <> -1 Then
                sRtrn += vbCrLf & "TABLA: " & myArray(i + 1) & " "
                nOccurs += 1
            ElseIf myArray(i).IndexOf("column") <> -1 Or myArray(i).IndexOf("columna") <> -1 Then
                sRtrn += vbCrLf & "COLUMNA: " & myArray(i + 1) & vbCrLf & vbCrLf
                nOccurs += 1
            End If
        Next

        'Retorno
        If nOccurs > 1 Then
            Return sRtrn
        End If
        Return Nothing

    End Function

    'Navega en una excepción para determinar si el error es del tipo FK
    Private Function GetTFKerror(ByVal ex As Exception) As String

        'Error no identificado
        If ex.Message.IndexOf("TABLE FOREIGN KEY") = -1 Then
            Return Nothing
        End If

        'Recorre el texto del error y arma el mensaje para el usuario
        Dim myArray() As String = ex.Message.Split(Chr(39))
        Dim nlongitud As Integer = myArray.GetLength(0)
        Dim i As Integer
        Dim nOccurs As Integer = 0
        Dim sRtrn As String = "Error de integridad referencial. "
        'If _dataset.Tables.Count > 1 Then
        '    sRtrn &= "posiblemente se deba a que no se pudo grabar el registro de la tabla principal debido a otros errores. "
        'End If

        For i = 0 To nlongitud - 1
            If myArray(i).IndexOf("tabla") <> -1 Or myArray(i).IndexOf("table") <> -1 Then
                sRtrn += vbCrLf & "TABLA: " & myArray(i + 1) & vbCrLf & vbCrLf & vbCrLf
                nOccurs += 1
            End If
        Next

        'Retorno
        If nOccurs > 1 Then
            Return sRtrn
        End If
        Return Nothing

    End Function

    'Navega en una excepción para determinar si el error es del tipo FK
    Private Function GetCFKerror(ByVal ex As Exception) As String

        'Error no identificado
        If ex.Message.IndexOf("COLUMN REFERENCE") = -1 Then
            Return Nothing
        End If

        'Recorre el texto del error y arma el mensaje para el usuario
        Dim myArray() As String = ex.Message.Split(Chr(39))
        Dim nlongitud As Integer = myArray.GetLength(0)
        Dim i As Integer
        Dim nOccurs As Integer = 0
        Dim sRtrn As String = "Error de integridad referencial. "
        If ex.Message.IndexOf("DELETE") <> -1 Then
            sRtrn += "No puede eliminar el registro en tanto exista en: "
        End If

        For i = 0 To nlongitud - 1
            If myArray(i).IndexOf("tabla") <> -1 Or myArray(i).IndexOf("table") <> -1 Then
                sRtrn += vbCrLf & "TABLA: " & myArray(i + 1) & " "
                nOccurs += 1
            ElseIf myArray(i).IndexOf("column") <> -1 Or myArray(i).IndexOf("columna") <> -1 Then
                sRtrn += vbCrLf & "COLUMNA: " & myArray(i + 1) & vbCrLf & vbCrLf
                nOccurs += 1
            End If
        Next

        'Retorno
        If nOccurs > 1 Then
            Return sRtrn
        End If
        Return Nothing

    End Function

    'Navega en una excepción para determinar si el error es del tipo FK
    Private Function GetTRFerror(ByVal ex As Exception) As String

        'Error no identificado
        If ex.Message.IndexOf("TABLE REFERENCE") = -1 Then
            Return Nothing
        End If

        'Recorre el texto del error y arma el mensaje para el usuario
        Dim myArray() As String = ex.Message.Split(Chr(39))
        Dim nlongitud As Integer = myArray.GetLength(0)
        Dim i As Integer
        Dim nOccurs As Integer = 0
        Dim sRtrn As String = "Error de integridad referencial. "
        If ex.Message.IndexOf("DELETE") <> -1 Then
            sRtrn += "No puede eliminar el registro en tanto exista en: "
        End If

        For i = 0 To nlongitud - 1
            If myArray(i).IndexOf("tabla") <> -1 Or myArray(i).IndexOf("table") <> -1 Then
                sRtrn += vbCrLf & "TABLA: " & myArray(i + 1) & " " & vbCrLf & vbCrLf & vbCrLf
                nOccurs += 1
            End If
        Next

        'Retorno
        If nOccurs > 0 Then
            Return sRtrn
        End If
        Return Nothing

    End Function
#End Region

End Class